#coding=utf-8
import numpy as np
import matplotlib.pyplot as plt

m = 101
x = np.linspace(-1, 1, m).reshape(-1, 1)      # 生成[-1, 1] 等距的101个点
y = 2 * x + np.random.randn(*x.shape) * 0.33  # 2x + 加随机噪声

plt.scatter(x, y)
# plt.show()
# input()
np.random.seed(2022)
w = np.random.randn(1)
b = np.random.randn(1)

def loss_fn(y, y_):
    return np.average((y - y_) **2)/2

def model(x):
    y_ = x * w + b
    return y_

def gradient(y, y_, x):
    dw = np.average((y_ - y) * x)
    db = np.average(y_ - y)
    return dw, db

learning_rate = 0.05
training_epoch = 201
xx = [-1, 1]
losses = [] #np.zeros((training_epoch, 1))
for epoch in range(training_epoch):
    y_ = model(x)
    dw, db = gradient(y, y_, x)
    w = w - dw * learning_rate
    b = b - db * learning_rate
    loss = loss_fn(y, y_)
    # losses[epoch] = loss
    losses.append(loss)
    if epoch % 40 == 0:

        print('Epoch [%d / %d], lose[%.3f], w / b[%.3f / %.3f]'
              % (epoch, training_epoch,
                 loss, w, b))
        plt.plot(xx, w * xx + b, label='epoch=%d' % epoch)
# zz = w * xx + b
# plt.plot(xx, zz, c='r', label='final')
plt.legend()
print(w, b)

plt.figure()
plt.plot(losses)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()